iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 19
0


這是一個表單,廢話。
我們先前設計了一個簡單的登入功能,但這些欄位都還沒有作用,今天我們來實作,如何從表單拿到使用者輸入的值,並且在以後接上API,送到後端伺服器。

<form>
  帳號 <input type="text"><br>
  密碼 <input type="password"><br>
 <input type="submit" value="Login" (click)="loginAction()">
</form>

這是原先的程式碼,我現在想要在 ts 看到這些欄位的值,我可以使用 Two-way Binding,那我們必須先宣告一組變數,然後跟 ngModel binding:

 // login.component.ts
login = {
     username: '',
     pwd : ''
 };

// login.component.html

<form
    帳號 <input type="text" [(ngModel)]="login.username"><br>
    密碼 <input type="password" [(ngModel)]="login.pwd"><br>
    <input type="submit" value="Login" (click)="loginAction()">
</form>

儲存之後會看到 F12 有錯誤訊息,它說,如果我們在 <form> 裡面用了 ngModel ,那該元素就要設定 name 這個欄位。OK,我們把 name 加上。

那在設定了 name 之後,就等於給 Angular 一個識別的名牌,這時我們可以在 <form> 加上範本參考變數,並指定為 ngForm,我這邊的變數名稱是 #f

<form #f="ngForm">

這個範本參考變數,可以當作是一個屬性來用,以井字號#開頭,後面接妳的變數名字 f、f123、aaaaa ...等都可以,做這樣的宣告之後,我們就可以在這份 html 裡,用這個變數名稱來存取DOM。
所以我們可以在下方,用這樣的方式來看表單內容:

{{f.value| json}}

f 是我們剛剛的 <form> 物件,然後取它的 value ,用前面學到的 Pipe 解析成 json 格式。
就可以看到表單目前的值:

不使用 pipe 的話,只會印出:

[object Object]

也可以試著比較,在範本參考變數後面指定 ngForm,印出來的內容有甚麼差別,下面的 #A 就是沒有指定 ngForm 的變數:

 // login.component.html
 
<form #f="ngForm" #A> ...</form>

{{f| json}}
<br>
<br>
{{A| json}}


字很小,但可以看的出來印出的結果不同。所以指定 ngForm,就會將變數解析成 Angular 自己的表單物件:

 // login.component.html
 
{{f}}
<br>
<br>
{{A}}

可以看出是兩種不同的 DOM 物件:

有了雙向綁定,我就可以在我按下 Login 按鈕時,抓我現在的變數值。

 loginAction() {
    this.loginRequest.emit(true);
    console.log(this.login);
  }

或是我們把範本參考變數的值傳進 function,我在 function 新增一個 $event 來接:

 // login.component.ts

  loginAction($event) {
    this.loginRequest.emit(true);
    console.log($event.value);
    }

然後在 (click)="loginAction() 的地方傳入 f,就是我們的 form 的變數。


 <form  #f="ngForm">
     ...
     <input type="submit" value="Login" (click)="loginAction(f)">
  </form>
 

可以印出一樣的東西:

習慣上我們會把 submit 的動作寫在 form 的屬性,所以我們把 loginAction() 移到 <form> 中跟 ngSubmit 做 Event Binding。此時再把 <input type="submit"> (click) 綁定拿掉。因為按下 Login 按鈕時,就會觸發 ngSubmit 了。

 // login.component.html

<form #f="ngForm" (ngSubmit)="loginAction(f)" >
    <input type="submit" value="Login">
</form>

且在 Submit 表單時,如果沒有執行 onSubmit(),貌似會跳出這個警告,(Angular 應該是認 onSubmit() 這個名字):

表單的功能不只這樣,你還可以透過 ngForm 屬性來取得表單的一些狀態,比方被點選過、未點選過、輸入過文字...等等,這些屬性同樣適用於 ngModel,也就是表單內每個標籤上都可以使用,只要在範本參考變數後面指派 ngModel就可以了,像這樣:

#name="ngModel"
 // login.component.html
 
 <form #f="ngForm >
    帳號 <input type="text" [(ngModel)]="login.username" name="username" 
    #name="ngModel"><br>
...
</form>
 
Form touched : {{f.touched}}<br>
Form untouched : {{f.untouched}}<br>
Form dirty : {{f.dirty}}<br>
Name touched : {{name.dirty}}<br>


上一篇
# DAY 18 Service
下一篇
# DAY 20 HttpClient (一)
系列文
從零開始的Angular前端開發30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言